home *** CD-ROM | disk | FTP | other *** search
- /*
- FMAZ41 -- Maze Game
-
- Version 4.1 (10/4/95)
-
-
- Generate and solve mazes on your VGA (or better) display.
-
- The mazes are displayed in three dimensions.
-
- You will be prompted for the number of columns, the tilt, the number of
- mazes to be tried before one is selected for display, and a random number seed.
-
- While the maze is being selected, a spinning cursor is displayed.
-
- After the maze is displayed, you may use the Home, PgUp, PgDn, End, up
- arrow, and down arrow keys to solve it. Press "Q" to quit or press "S" to have
- the computer solve the maze.
-
- After the maze is solved, you must press some key to continue.
-
- Each maze has exactly one solution that does not involve backtracking
- (passing through a doorway more than once).
-
- This program was written by James L. Dean.
-
- */
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <dos.h>
- #include <graphics.h>
-
- typedef struct corner_record
- {
- int x;
- int y;
- } corner_rec;
-
- typedef struct vertex_record
- {
- double x;
- double y;
- } vertex_rec;
-
- typedef struct rectangle_record
- {
- vertex_rec vertex [4];
- } rectangle_rec;
-
- typedef struct stack_rec_record
- {
- char index_1;
- int index_2;
- } stack_rec;
-
- #define TRUE 1
- #define FALSE 0
-
- #define GRAPHICS_DRIVER VGA /* 640x480x16 VGA */
- #define GRAPHICS_MODE VGAHI /* must support red, green, yellow,
- and 9 shades of gray */
- #define NUM_COLORS 16
- #define TOP_COLOR 12 /* all but last 3 colors are gray */
- #define RIGHT_WALL_COLOR 10
- #define FRONT_WALL_COLOR 7
- #define FLOOR_COLOR 6
- #define LEFT_WALL_COLOR 4
- #define BACKOUT_COLOR 13
- #define ADVANCE_COLOR 14
- #define SOLUTION_COLOR 15
- #define WIDTH_OF_GRAPHICS_IN_INCHES 8.0
- #define NUM_X_PIXELS 640
- #define WIDTH_OF_GRAPHICS_IN_PIXELS 640
- #define HEIGHT_OF_GRAPHICS_IN_INCHES 5.0
- #define NUM_Y_PIXELS 480
- #define HEIGHT_OF_GRAPHICS_IN_PIXELS 400
-
- #define RELATIVE_WIDTH_OF_WALL 0.2 /* relative to side of square */
- #define RELATIVE_HEIGHT_OF_WALL 1.0 /* relative to side of square */
- #define MIN_WALL_LENGTH_IN_PIXELS 12
-
- static void display_quadrilateral(double,double,double,double,double,
- double,double,double,double,double,double,double,double,
- double,double,double,double,double,double,double,int);
- static void display_solution(int,int,char **,double,double,double,
- double,double,double,double,double);
- static void draw_line(double,double,double,double,double,double,
- double,double,double,double,double,double);
- static void free_memory(char ***,char ***,int,stack_rec **);
- static void generate_maze(char **,int,int,stack_rec *,int,int,int *);
- static void get_corner(double,double,double,double,double,double,
- double,double,double,double,double,corner_rec *);
- static void get_cursor(unsigned char *,unsigned char *,
- unsigned char *,unsigned char *);
- static void get_defaults(char *,int *,double *,char *,long *);
- static void hash(int *,int *,int *,int *,int *,int *,int *,int *);
- static void increment(int *,int *,int *,int *,int *,int *,int *,
- int *);
- static void let_user_try_to_solve(int *,int,int,char **,char **,
- double,double,double,double,double,double,double,double);
- int main(int,char **);
- static int memory_allocated(char ***,char ***,int,int,stack_rec **,
- int);
- void interrupt new_critical_error_handler(void);
- void interrupt (*old_critical_error_handler)(void);
- static void output_maze(char **,int,int,double,double,double,double,
- double,double,double,double);
- static void output_front_top(double,double,double,rectangle_rec *,
- double,double,double,double,double);
- static void output_left_right(double,double,double,rectangle_rec *,
- double,double,double,double,double);
- static void put_defaults(char *,int,double,char *,long);
- static void select_maze(char *,char **,int,int,stack_rec *,int,int,
- int,long);
- static void set_cursor_position(unsigned char,unsigned char);
- static void set_cursor_size(unsigned char,unsigned char);
- static void solve_maze(stack_rec *,char **,int *,int *,int,int);
- static void titillate(void);
-
- extern unsigned _stklen=0x8000;
-
- static unsigned char cursor_column;
- static unsigned char cursor_row;
- static unsigned char cursor_start;
- static unsigned char cursor_stop;
- static int delta_x [4] [24];
- static int delta_y [4] [24];
- static int file_opened;
- static char titillator [4] = {'|','/','-','\\'};
- static int titillator_index;
-
- int main(
- int argc,
- char *argv[])
- {
- register int color_num;
- static char **computer_page;
- static double cos_tilt;
- static int default_num_columns;
- static long default_num_trials;
- static char default_seed [256];
- static double default_tilt;
- static int delta_index_1a;
- static int delta_index_1b;
- static int delta_index_1c;
- static int delta_index_1d;
- static int delta_index_2;
- static int ErrorCode;
- static int fatal_error;
- static int GraphDriver;
- static int GraphMode;
- static char line [256];
- static char *line_ptr;
- static int max_num_columns;
- static int max_x;
- static int max_x_plus_1;
- static int max_y;
- static int max_y_plus_1;
- static int min_num_columns;
- static int num_assigned;
- static int num_columns;
- static int num_rooms_in_maze;
- static int num_rows;
- static long num_trials;
- static struct palettetype palette;
- static double pixels_per_x;
- static double pixels_per_z;
- static double radians;
- static double radians_per_degree;
- static double rel_dist_of_user_from_screen;
- static int response;
- static char seed [256];
- static int seed_index;
- static double sin_tilt;
- static stack_rec *stack;
- static double tilt;
- static int tint;
- static char **user_page;
- static int user_still_interested;
- static double x_max;
- static double x_offset;
- static double y_max;
-
- fatal_error=FALSE;
- delta_x[0][0]=-1;
- delta_y[0][0]=0;
- delta_x[1][0]=0;
- delta_y[1][0]=1;
- delta_x[2][0]=1;
- delta_y[2][0]=0;
- delta_x[3][0]=0;
- delta_y[3][0]=-1;
- delta_index_2=0;
- for (delta_index_1a=0; delta_index_1a < 4; delta_index_1a++)
- for (delta_index_1b=0; delta_index_1b < 4; delta_index_1b++)
- if (delta_index_1a != delta_index_1b)
- for (delta_index_1c=0; delta_index_1c < 4; delta_index_1c++)
- if ((delta_index_1a != delta_index_1c)
- && (delta_index_1b != delta_index_1c))
- for (delta_index_1d=0; delta_index_1d < 4; delta_index_1d++)
- if ((delta_index_1a != delta_index_1d)
- && (delta_index_1b != delta_index_1d)
- && (delta_index_1c != delta_index_1d))
- {
- delta_x[delta_index_1a][delta_index_2]
- =delta_x[0][0];
- delta_y[delta_index_1a][delta_index_2]
- =delta_y[0][0];
- delta_x[delta_index_1b][delta_index_2]
- =delta_x[1][0];
- delta_y[delta_index_1b][delta_index_2]
- =delta_y[1][0];
- delta_x[delta_index_1c][delta_index_2]
- =delta_x[2][0];
- delta_y[delta_index_1c][delta_index_2]
- =delta_y[2][0];
- delta_x[delta_index_1d][delta_index_2]
- =delta_x[3][0];
- delta_y[delta_index_1d][delta_index_2]
- =delta_y[3][0];
- delta_index_2++;
- };
- min_num_columns=2;
- max_num_columns=(int) (((double) WIDTH_OF_GRAPHICS_IN_PIXELS)/
- ((double) MIN_WALL_LENGTH_IN_PIXELS)-RELATIVE_WIDTH_OF_WALL);
- get_defaults(argv[0],&default_num_columns,&default_tilt,&default_seed[0],
- &default_num_trials);
- do
- {
- clrscr();
- printf(
- " FMAZ41 -- Maze Game\n\n"
- " Version 4.1 (10/4/95)\n\n\n"
- " Generate and solve mazes on your VGA (or better) display.\n\n"
- " The mazes are displayed in three dimensions.\n\n"
- " To get the value surrounded by [], just press Enter.\n\n");
- do
- {
- printf(" Number of columns (%d to %d, or 0 to exit) [%d]? ",
- min_num_columns,max_num_columns,default_num_columns);
- fflush(stdin);
- fgets(&line[0],256,stdin);
- line_ptr=&line[0];
- while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
- line_ptr++;
- if ((*line_ptr == '\n') || (*line_ptr == '\0'))
- num_columns=default_num_columns;
- else
- {
- num_assigned=sscanf(line_ptr,"%d",&num_columns);
- if ((num_assigned == 0) || (num_assigned == EOF))
- num_columns=-1;
- }
- }
- while ((num_columns != 0)
- && ((num_columns < min_num_columns)
- || (num_columns > max_num_columns)));
- user_still_interested=num_columns;
- if (user_still_interested)
- {
- printf("\n");
- num_rows=(int) (((double) HEIGHT_OF_GRAPHICS_IN_INCHES)
- *((double) num_columns)/((double) WIDTH_OF_GRAPHICS_IN_INCHES));
- if (num_rows < 2)
- num_rows=2;
- do
- {
- printf(" Tilt (30 to 60 degrees) [%lf]? ",default_tilt);
- fflush(stdin);
- fgets(&line[0],256,stdin);
- line_ptr=&line[0];
- while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
- line_ptr++;
- if ((*line_ptr == '\n') || (*line_ptr == '\0'))
- tilt=default_tilt;
- else
- {
- num_assigned=sscanf(line_ptr,"%lf",&tilt);
- if ((num_assigned == 0) || (num_assigned == EOF))
- tilt=(double) 0.0;
- }
- }
- while ((tilt < (double) 30.0) || (tilt > (double) 60.0));
- printf("\n");
- do
- {
- printf(" Number of trials to allow for maze selection "
- "[%ld]? ",default_num_trials);
- fflush(stdin);
- fgets(&line[0],256,stdin);
- line_ptr=&line[0];
- while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
- line_ptr++;
- if ((*line_ptr == '\n') || (*line_ptr == '\0'))
- num_trials=default_num_trials;
- else
- {
- num_assigned=sscanf(line_ptr,"%ld",&num_trials);
- if ((num_assigned == 0) || (num_assigned == EOF))
- num_trials=0;
- }
- }
- while (num_trials <= 0L);
- printf("\n Random number seed (8 or fewer digits) [%s]? ",
- &default_seed[0]);
- fflush(stdin);
- fgets(&line[0],256,stdin);
- line_ptr=&line[0];
- while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
- line_ptr++;
- if ((*line_ptr != '\n') && (*line_ptr != '\0'))
- {
- seed_index=0;
- while ((seed_index < 8)
- && (*line_ptr)
- && (*line_ptr != '\n'))
- default_seed[seed_index++]=*(line_ptr++);
- default_seed[seed_index]='\0';
- }
- strcpy(&seed[0],&default_seed[0]);
- default_num_columns=num_columns;
- default_tilt=tilt;
- default_num_trials=num_trials;
- max_x=2*num_columns;
- max_x_plus_1=max_x+1;
- max_y=2*num_rows;
- max_y_plus_1=max_y+1;
- num_rooms_in_maze=num_rows*num_columns;
- if (memory_allocated(&computer_page,&user_page,max_x_plus_1,
- max_y_plus_1,&stack,num_rooms_in_maze))
- {
- printf(
- "\n While the maze is being selected, a spinning cursor is displayed: ");
- select_maze(&seed[0],computer_page,max_x,max_y,stack,
- num_rooms_in_maze,num_columns,num_rows,num_trials);
- registerbgidriver(EGAVGA_driver);
- /*
- See the Borland documentation on the
- utilities "BINOBJ" and "TLIB" for
- information on how to link "EGAVGA.BGI"
- into a program from "GRAPHICS.LIB".
- */
- GraphDriver=GRAPHICS_DRIVER;
- GraphMode=GRAPHICS_MODE;
- initgraph(&GraphDriver,&GraphMode,"");
- ErrorCode=graphresult();
- if (ErrorCode == 0)
- {
- getpalette(&palette);
- for (color_num=0;
- color_num < (NUM_COLORS-3);
- color_num++)
- { /* evenly spaced shades of gray */
- tint=(63*color_num)/(NUM_COLORS-3);
- tint&=0xfc;
- setrgbpalette(
- palette.colors[color_num],
- tint,tint,tint);
- }
- setrgbpalette(
- palette.colors[BACKOUT_COLOR],
- 0xfc,0xfc,0);
- setrgbpalette(
- palette.colors[ADVANCE_COLOR],
- 0,0xfc,0);
- setrgbpalette(
- palette.colors[SOLUTION_COLOR],
- 0xfc,0,0);
- settextjustify(CENTER_TEXT,BOTTOM_TEXT);
- settextstyle(DEFAULT_FONT,HORIZ_DIR,0);
- setcolor(NUM_COLORS-4);
- outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
- "Arrows - Move S - Solve Q - Quit");
- radians_per_degree=atan(1.0)/45.0;
- radians=tilt*radians_per_degree;
- sin_tilt=sin(radians);
- cos_tilt=cos(radians);
- x_max=((double) num_columns)+RELATIVE_WIDTH_OF_WALL;
- pixels_per_x
- =(((double) WIDTH_OF_GRAPHICS_IN_PIXELS)-1.0)
- /(x_max*(x_max/(x_max-RELATIVE_HEIGHT_OF_WALL)));
- x_offset=(x_max/2.0)*(RELATIVE_HEIGHT_OF_WALL
- /(x_max-RELATIVE_HEIGHT_OF_WALL));
- y_max=((double) num_rows)+RELATIVE_WIDTH_OF_WALL;
- pixels_per_z
- =(((double) HEIGHT_OF_GRAPHICS_IN_PIXELS)-1.0)
- /sqrt(y_max*y_max
- +RELATIVE_HEIGHT_OF_WALL*RELATIVE_HEIGHT_OF_WALL);
- if (y_max > x_max)
- rel_dist_of_user_from_screen=y_max;
- else
- rel_dist_of_user_from_screen=x_max;
- output_maze(computer_page,max_x,max_y,x_max,x_offset,
- y_max,cos_tilt,sin_tilt,pixels_per_x,pixels_per_z,
- rel_dist_of_user_from_screen);
- let_user_try_to_solve(&response,max_x,max_y,computer_page,
- user_page,x_max,x_offset,y_max,cos_tilt,sin_tilt,
- pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
- if ((response == (int) 's')
- || (response == (int) 'S'))
- {
- display_solution(max_x,max_y,computer_page,x_max,
- x_offset,y_max,cos_tilt,sin_tilt,pixels_per_x,
- pixels_per_z,rel_dist_of_user_from_screen);
- setcolor(NUM_COLORS-4);
- outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
- "Press a key to continue.");
- response=getch();
- if (response == 0)
- response=getch();
- }
- closegraph();
- }
- else
- {
- printf(" Fatal error: %s\n",
- grapherrormsg(ErrorCode));
- fatal_error=TRUE;
- }
- free_memory(&computer_page,&user_page,max_y_plus_1,&stack);
- }
- else
- {
- fatal_error=TRUE;
- printf(" Fatal error: out of memory.\n");
- }
- }
- }
- while ((! fatal_error) && (user_still_interested));
- if (! fatal_error)
- put_defaults(argv[0],default_num_columns,default_tilt,
- &default_seed[0],default_num_trials);
- return fatal_error;
- }
-
- static void get_defaults(
- char *argv,
- int *default_num_columns,
- double *default_tilt,
- char *default_seed,
- long *default_num_trials)
- {
- register int arg_index;
- static char *arg_ptr;
- FILE *defaults;
- static char file_name [256];
- static int last_period_index;
- static char line [256];
- static char *line_ptr;
- static int num_assigned;
- static int seed_length;
- static char *seed_ptr;
-
- arg_index=0;
- arg_ptr=argv;
- last_period_index=-1;
- while ((*arg_ptr) && (arg_index < 252))
- {
- if (*arg_ptr == '.')
- last_period_index=arg_index;
- file_name[arg_index++]=*(arg_ptr++);
- }
- if ((*arg_ptr) || (last_period_index < 0))
- {
- *default_num_columns=30;
- *default_tilt=(double) 30.0;
- default_seed[0]='1';
- default_seed[1]='\0';
- }
- else
- {
- file_name[++last_period_index]='I';
- file_name[++last_period_index]='N';
- file_name[++last_period_index]='I';
- file_name[++last_period_index]='\0';
- if ((defaults=fopen(&file_name[0],"r")) == NULL)
- {
- *default_num_columns=30;
- *default_tilt=(double) 30.0;
- default_seed[0]='1';
- default_seed[1]='\0';
- *default_num_trials=5L;
- }
- else
- {
- line_ptr=fgets(&line[0],256,defaults);
- if (line_ptr == NULL)
- {
- *default_num_columns=30;
- *default_tilt=(double) 30.0;
- default_seed[0]='1';
- default_seed[1]='\0';
- *default_num_trials=5L;
- }
- else
- {
- while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
- line_ptr++;
- if ((*line_ptr == '\n') || (*line_ptr == '\0'))
- *default_num_columns=30;
- else
- {
- num_assigned=sscanf(line_ptr,"%d",default_num_columns);
- if ((num_assigned == 0) || (num_assigned == EOF))
- *default_num_columns=30;
- }
- line_ptr=fgets(&line[0],256,defaults);
- if (line_ptr == NULL)
- {
- *default_tilt=(double) 30.0;
- default_seed[0]='1';
- default_seed[1]='\0';
- *default_num_trials=5L;
- }
- else
- {
- while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
- line_ptr++;
- if ((*line_ptr == '\n') || (*line_ptr == '\0'))
- *default_tilt=(double) 30.0;
- else
- {
- num_assigned=sscanf(line_ptr,"%lf",default_tilt);
- if ((num_assigned == 0) || (num_assigned == EOF))
- *default_tilt=(double) 30.0;
- }
- line_ptr=fgets(&line[0],256,defaults);
- if (line_ptr == NULL)
- {
- default_seed[0]='1';
- default_seed[1]='\0';
- *default_num_trials=5L;
- }
- else
- {
- while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
- line_ptr++;
- seed_ptr=default_seed;
- if ((*line_ptr == '\n') || (*line_ptr == '\0'))
- *(seed_ptr++)='1';
- else
- {
- seed_length=0;
- while ((seed_length < 8)
- && (*line_ptr)
- && (*line_ptr != '\n'))
- {
- *(seed_ptr++)=*(line_ptr++);
- seed_length++;
- }
- }
- *seed_ptr='\0';
- line_ptr=fgets(&line[0],256,defaults);
- if (line_ptr == NULL)
- *default_num_trials=5L;
- else
- {
- while ((*line_ptr == ' ')
- || (*line_ptr == (char) 9))
- line_ptr++;
- if ((*line_ptr == '\n') || (*line_ptr == '\0'))
- *default_num_trials=5L;
- else
- {
- num_assigned
- =sscanf(line_ptr,"%ld",default_num_trials);
- if ((num_assigned == 0)
- || (num_assigned == EOF))
- *default_num_trials=5L;
- }
- }
- }
- }
- }
- fclose(defaults);
- }
- }
- return;
- }
-
- void interrupt new_critical_error_handler()
- {
- file_opened=FALSE;
- return;
- }
-
- static void put_defaults(
- char *argv,
- int num_columns,
- double tilt,
- char *seed,
- long num_trials)
- {
- static int arg_index;
- static char *arg_ptr;
- FILE *defaults;
- static char file_name [256];
- static int last_period_index;
-
- arg_index=0;
- arg_ptr=argv;
- last_period_index=-1;
- while ((*arg_ptr) && (arg_index < 252))
- {
- if (*arg_ptr == '.')
- last_period_index=arg_index;
- file_name[arg_index++]=*(arg_ptr++);
- }
- if ((*arg_ptr == '\0') && (last_period_index >= 0))
- {
- file_name[++last_period_index]='I';
- file_name[++last_period_index]='N';
- file_name[++last_period_index]='I';
- file_name[++last_period_index]='\0';
- old_critical_error_handler=getvect(0x24);
- setvect(0x24,new_critical_error_handler);
- file_opened=TRUE;
- if ((defaults=fopen(&file_name[0],"w")) != NULL)
- {
- setvect(0x24,old_critical_error_handler);
- if (file_opened)
- {
- fprintf(defaults,"%d\n%lf\n%s\n%ld\n",num_columns,tilt,seed,
- num_trials);
- fclose(defaults);
- }
- }
- else
- setvect(0x24,old_critical_error_handler);
- }
- return;
- }
-
- static void get_corner(
- double x,
- double y,
- double z,
- double pixels_per_x,
- double pixels_per_z,
- double cos_tilt,
- double sin_tilt,
- double rel_dist_of_user_from_screen,
- double x_max,
- double x_offset,
- double y_max,
- corner_rec *corner)
- {
- double x_adjusted;
- double y_prime;
- double z_adjusted;
- double z_prime;
-
- y_prime=(y_max-y)*cos_tilt-z*sin_tilt;
- z_prime=(y_max-y)*sin_tilt+z*cos_tilt;
- z_adjusted=(y_max/2.0)+rel_dist_of_user_from_screen
- *(z_prime-(y_max/2.0))/(y_prime+rel_dist_of_user_from_screen);
- x_adjusted=(x_max/2.0)+rel_dist_of_user_from_screen
- *(x-(x_max/2.0))/(y_prime+rel_dist_of_user_from_screen);
- x_adjusted+=x_offset;
- corner->x=(int) (pixels_per_x*x_adjusted);
- corner->y
- =(HEIGHT_OF_GRAPHICS_IN_PIXELS-1)-((int) (pixels_per_z*z_adjusted));
- return;
- }
-
- static void display_quadrilateral(
- double x_max,
- double x_offset,
- double y_max,
- double x0,
- double y0,
- double z0,
- double x1,
- double y1,
- double z1,
- double x2,
- double y2,
- double z2,
- double x3,
- double y3,
- double z3,
- double pixels_per_x,
- double pixels_per_z,
- double cos_tilt,
- double sin_tilt,
- double rel_dist_of_user_from_screen,
- int color)
- {
- static corner_rec quadrilateral [4];
-
- get_corner(x0,y0,z0,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[0]);
- get_corner(x1,y1,z1,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[1]);
- get_corner(x2,y2,z2,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[2]);
- get_corner(x3,y3,z3,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[3]);
- setcolor(color);
- setfillstyle(SOLID_FILL,color);
- fillpoly(4,&(quadrilateral[0].x));
- return;
- }
-
- static void output_front_top(
- double x_max,
- double x_offset,
- double y_max,
- rectangle_rec *rectangle,
- double pixels_per_x,
- double pixels_per_z,
- double cos_tilt,
- double sin_tilt,
- double rel_dist_of_user_from_screen)
- {
- display_quadrilateral(x_max,x_offset,y_max,
- (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,
- RELATIVE_HEIGHT_OF_WALL,
- (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,
- RELATIVE_HEIGHT_OF_WALL,
- (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,0.0,
- (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,0.0,
- pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen,FRONT_WALL_COLOR);
- display_quadrilateral(x_max,x_offset,y_max,
- (*rectangle).vertex[0].x,(*rectangle).vertex[0].y,
- RELATIVE_HEIGHT_OF_WALL,
- (*rectangle).vertex[1].x,(*rectangle).vertex[1].y,
- RELATIVE_HEIGHT_OF_WALL,
- (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,
- RELATIVE_HEIGHT_OF_WALL,
- (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,
- RELATIVE_HEIGHT_OF_WALL,
- pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen,TOP_COLOR);
- return;
- }
-
- static void output_left_right(
- double x_max,
- double x_offset,
- double y_max,
- rectangle_rec *rectangle,
- double pixels_per_x,
- double pixels_per_z,
- double cos_tilt,
- double sin_tilt,
- double rel_dist_of_user_from_screen)
- {
- if (2.0*(*rectangle).vertex[0].x > x_max)
- display_quadrilateral(x_max,x_offset,y_max,
- (*rectangle).vertex[0].x,(*rectangle).vertex[0].y,
- RELATIVE_HEIGHT_OF_WALL,
- (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,
- RELATIVE_HEIGHT_OF_WALL,
- (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,0.0,
- (*rectangle).vertex[0].x,(*rectangle).vertex[0].y,0.0,
- pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen,RIGHT_WALL_COLOR);
- if (2.0*(*rectangle).vertex[1].x < x_max)
- display_quadrilateral(x_max,x_offset,y_max,
- (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,
- RELATIVE_HEIGHT_OF_WALL,
- (*rectangle).vertex[1].x,(*rectangle).vertex[1].y,
- RELATIVE_HEIGHT_OF_WALL,
- (*rectangle).vertex[1].x,(*rectangle).vertex[1].y,0.0,
- (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,0.0,
- pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen,LEFT_WALL_COLOR);
- return;
- }
-
- static void output_maze(
- char **page,
- int max_x,
- int max_y,
- double x_max,
- double x_offset,
- double y_max,
- double cos_tilt,
- double sin_tilt,
- double pixels_per_x,
- double pixels_per_z,
- double rel_dist_of_user_from_screen)
- {
- static rectangle_rec base_rectangle [4];
- static int object_num;
- static rectangle_rec rectangle [4];
- static int vertex_num;
- register int x;
- register int y;
- static double y_offset;
-
- base_rectangle[0].vertex[0].x=0.0;
- base_rectangle[0].vertex[0].y=0.0;
- base_rectangle[0].vertex[1].x=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[0].vertex[1].y=0.0;
- base_rectangle[0].vertex[2].x=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[0].vertex[2].y=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[0].vertex[3].x=0.0;
- base_rectangle[0].vertex[3].y=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[1].vertex[0].x=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[1].vertex[0].y=0.0;
- base_rectangle[1].vertex[1].x=1.0;
- base_rectangle[1].vertex[1].y=0.0;
- base_rectangle[1].vertex[2].x=1.0;
- base_rectangle[1].vertex[2].y=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[1].vertex[3].x=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[1].vertex[3].y=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[2].vertex[0].x=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[2].vertex[0].y=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[2].vertex[1].x=1.0;
- base_rectangle[2].vertex[1].y=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[2].vertex[2].x=1.0;
- base_rectangle[2].vertex[2].y=1.0;
- base_rectangle[2].vertex[3].x=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[2].vertex[3].y=1.0;
- base_rectangle[3].vertex[0].x=0.0;
- base_rectangle[3].vertex[0].y=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[3].vertex[1].x=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[3].vertex[1].y=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[3].vertex[2].x=RELATIVE_WIDTH_OF_WALL;
- base_rectangle[3].vertex[2].y=1.0;
- base_rectangle[3].vertex[3].x=0.0;
- base_rectangle[3].vertex[3].y=1.0;
- rectangle[0].vertex[0].x=0.0;
- rectangle[0].vertex[0].y=0.0;
- rectangle[0].vertex[1].x=x_max;
- rectangle[0].vertex[1].y=0.0;
- rectangle[0].vertex[2].x=x_max;
- rectangle[0].vertex[2].y=y_max;
- rectangle[0].vertex[3].x=0.0;
- rectangle[0].vertex[3].y=y_max;
- display_quadrilateral(x_max,x_offset,y_max,
- rectangle[object_num].vertex[0].x,rectangle[object_num].vertex[0].y,0.0,
- rectangle[object_num].vertex[1].x,rectangle[object_num].vertex[1].y,0.0,
- rectangle[object_num].vertex[2].x,rectangle[object_num].vertex[2].y,0.0,
- rectangle[object_num].vertex[3].x,rectangle[object_num].vertex[3].y,0.0,
- pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,rel_dist_of_user_from_screen,
- FLOOR_COLOR);
- y_offset=0.0;
- y=0;
- while (y <= max_y)
- {
- for (vertex_num=0; vertex_num < 4; vertex_num++)
- {
- rectangle[0].vertex[vertex_num].x
- =base_rectangle[0].vertex[vertex_num].x;
- rectangle[0].vertex[vertex_num].y
- =base_rectangle[0].vertex[vertex_num].y+y_offset;
- }
- x=0;
- while (x <= max_x)
- {
- if (page[y][x] == 'W')
- output_left_right(x_max,x_offset,y_max,&rectangle[0],
- pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen);
- for (vertex_num=0; vertex_num < 4; vertex_num++)
- (rectangle[0].vertex[vertex_num].x)++;
- x++;
- x++;
- }
- for (vertex_num=0; vertex_num < 4; vertex_num++)
- {
- rectangle[0].vertex[vertex_num].x
- =base_rectangle[0].vertex[vertex_num].x;
- rectangle[0].vertex[vertex_num].y
- =base_rectangle[0].vertex[vertex_num].y+y_offset;
- }
- for (vertex_num=0; vertex_num < 4; vertex_num++)
- {
- rectangle[1].vertex[vertex_num].x
- =base_rectangle[1].vertex[vertex_num].x;
- rectangle[1].vertex[vertex_num].y
- =base_rectangle[1].vertex[vertex_num].y+y_offset;
- }
- x=0;
- while (x <= max_x)
- {
- if (page[y][x] == 'W')
- output_front_top(x_max,x_offset,y_max,&rectangle[0],
- pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen);
- for (vertex_num=0; vertex_num < 4; vertex_num++)
- (rectangle[0].vertex[vertex_num].x)++;
- x++;
- if (x <= max_x)
- {
- if (page[y][x] == 'W')
- output_front_top(x_max,x_offset,y_max,&rectangle[1],
- pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen);
- for (vertex_num=0; vertex_num < 4; vertex_num++)
- (rectangle[1].vertex[vertex_num].x)++;
- x++;
- }
- }
- y++;
- if (y <= max_y)
- {
- for (vertex_num=0; vertex_num < 4; vertex_num++)
- {
- rectangle[3].vertex[vertex_num].x
- =base_rectangle[3].vertex[vertex_num].x;
- rectangle[3].vertex[vertex_num].y
- =base_rectangle[3].vertex[vertex_num].y+y_offset;
- }
- x=0;
- while (x <= max_x)
- {
- if (page[y][x] == 'W')
- output_left_right(x_max,x_offset,y_max,&rectangle[3],
- pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen);
- for (vertex_num=0; vertex_num < 4; vertex_num++)
- (rectangle[3].vertex[vertex_num].x)++;
- x++;
- x++;
- }
- for (vertex_num=0; vertex_num < 4; vertex_num++)
- {
- rectangle[3].vertex[vertex_num].x
- =base_rectangle[3].vertex[vertex_num].x;
- rectangle[3].vertex[vertex_num].y
- =base_rectangle[3].vertex[vertex_num].y+y_offset;
- }
- x=0;
- while (x <= max_x)
- {
- if (page[y][x] == 'W')
- output_front_top(x_max,x_offset,y_max,&rectangle[3],
- pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
- rel_dist_of_user_from_screen);
- for (vertex_num=0; vertex_num < 4; vertex_num++)
- (rectangle[3].vertex[vertex_num].x)++;
- x++;
- x++;
- }
- y++;
- }
- y_offset++;
- }
- return;
- }
-
- static int memory_allocated(
- char ***computer_page,
- char ***user_page,
- int max_x_plus_1,
- int max_y_plus_1,
- stack_rec **stack,
- int num_rooms_in_maze)
- {
- static int result;
- register int y;
-
- if (((*computer_page)
- =(char **) malloc(((size_t) max_y_plus_1)*sizeof(char *))) == NULL)
- result=FALSE;
- else
- {
- result=TRUE;
- for (y=0; ((result) && (y < max_y_plus_1)); y++)
- result=(((*computer_page)[y]
- =malloc(((size_t) max_x_plus_1)*sizeof(char))) != NULL);
- if (! result)
- {
- --y;
- while (y > 0)
- free((void *) (*computer_page)[--y]);
- free((void *) *computer_page);
- }
- }
- if (result)
- {
- if (((*user_page)
- =(char **) malloc(((size_t) max_y_plus_1)*sizeof(char *))) == NULL)
- {
- result=FALSE;
- for (y=0; y < max_y_plus_1; y++)
- free((void *) (*computer_page)[y]);
- free((void *) *computer_page);
- }
- else
- {
- result=TRUE;
- for (y=0; ((result) && (y < max_y_plus_1)); y++)
- result=(((*user_page)[y]
- =malloc(((size_t) max_x_plus_1)*sizeof(char))) != NULL);
- if (! result)
- {
- --y;
- while (y > 0)
- free((void *) (*user_page)[--y]);
- free((void *) *user_page);
- for (y=0; y < max_y_plus_1; y++)
- free((void *) (*computer_page)[y]);
- free((void *) *computer_page);
- }
- }
- }
- if (result)
- {
- if ((*stack=(stack_rec *) malloc(
- ((unsigned int) num_rooms_in_maze)*sizeof(stack_rec))) == NULL)
- {
- result=FALSE;
- for (y=0; y < max_y_plus_1; y++)
- free((void *) (*user_page)[y]);
- free((void *) *user_page);
- for (y=0; y < max_y_plus_1; y++)
- free((void *) (*computer_page)[y]);
- free((void *) *computer_page);
- }
- }
- return(result);
- }
-
- static void free_memory(
- char ***computer_page,
- char ***user_page,
- int max_y_plus_1,
- stack_rec **stack)
- {
- register int y;
-
- free((void *) *stack);
- for (y=0; y < max_y_plus_1; y++)
- free((void *) (*user_page)[y]);
- free((void *) *user_page);
- for (y=0; y < max_y_plus_1; y++)
- free((void *) (*computer_page)[y]);
- free((void *) *computer_page);
- return;
- }
-
- static void get_cursor(
- unsigned char *cursor_row,
- unsigned char *cursor_column,
- unsigned char *cursor_start,
- unsigned char *cursor_stop)
- {
- static union REGS in;
- static union REGS out;
-
- in.h.ah=(unsigned char) 3;
- in.h.bh=(unsigned char) 0;
- int86(0x10,&in,&out);
- *cursor_row=out.h.dh;
- *cursor_column=out.h.dl;
- *cursor_start=out.h.ch;
- *cursor_stop=out.h.cl;
- return;
- }
-
- static void set_cursor_position(
- unsigned char cursor_row,
- unsigned char cursor_column)
- {
- static union REGS in;
- static union REGS out;
-
- in.h.ah=(unsigned char) 2;
- in.h.dh=cursor_row;
- in.h.dl=cursor_column;
- int86(0x10,&in,&out);
- return;
- }
-
- static void set_cursor_size(
- unsigned char cursor_start,
- unsigned char cursor_stop)
- {
- static union REGS in;
- static union REGS out;
-
- in.h.ah=(unsigned char) 1;
- in.h.ch=cursor_start;
- in.h.cl=cursor_stop;
- int86(0x10,&in,&out);
- return;
- }
-
- static void titillate()
- {
- set_cursor_position(cursor_row,cursor_column);
- titillator_index++;
- if (titillator_index > 3)
- titillator_index=0;
- putchar((int) titillator[titillator_index]);
- return;
- }
-
- static void solve_maze(
- stack_rec *stack,
- char **page,
- int *num_rooms_in_solution,
- int *adjacency,
- int max_x,
- int max_y)
- {
- int delta_index;
- int passage_found;
- int stack_head;
- int x;
- int x_next;
- int y;
- int y_next;
-
- *num_rooms_in_solution=1;
- *adjacency=0;
- x=1;
- y=1;
- stack_head=-1;
- page[y][x]='S';
- do
- {
- delta_index=0;
- passage_found=FALSE;
- do
- {
- while ((delta_index < 4) && (! passage_found))
- {
- x_next=x+delta_x[delta_index][0];
- y_next=y+delta_y[delta_index][0];
- if (page[y_next][x_next] == ' ')
- passage_found=TRUE;
- else
- delta_index++;
- }
- if (! passage_found)
- {
- delta_index=(int) (stack[stack_head].index_1);
- page[y][x]=' ';
- x-=delta_x[delta_index][0];
- y-=delta_y[delta_index][0];
- page[y][x]=' ';
- x-=delta_x[delta_index][0];
- y-=delta_y[delta_index][0];
- stack_head--;
- delta_index++;
- }
- }
- while (! passage_found);
- page[y_next][x_next]='S';
- x_next+=delta_x[delta_index][0];
- y_next+=delta_y[delta_index][0];
- if (y_next <= max_y)
- {
- stack_head++;
- stack[stack_head].index_1=(char) delta_index;
- page[y_next][x_next]='S';
- x=x_next;
- y=y_next;
- }
- }
- while (y_next < max_y);
- x=max_x-1;
- y=max_y-1;
- *adjacency=0;
- while (stack_head >= 0)
- {
- for (delta_index=0; delta_index < 4; delta_index++)
- {
- x_next=x+delta_x[delta_index][0];
- y_next=y+delta_y[delta_index][0];
- if (page[y_next][x_next] != 'S')
- {
- if (page[y_next][x_next] == 'W')
- {
- x_next+=delta_x[delta_index][0];
- y_next+=delta_y[delta_index][0];
- if (x_next < 0)
- (*adjacency)++;
- else
- if (x_next > max_x)
- (*adjacency)++;
- else
- if (y_next < 0)
- (*adjacency)++;
- else
- if (y_next > max_y)
- (*adjacency)++;
- else
- {
- if (page[y_next][x_next] == 'S')
- (*adjacency)++;
- }
- }
- }
- }
- x-=(2*delta_x[stack[stack_head].index_1][0]);
- y-=(2*delta_y[stack[stack_head].index_1][0]);
- stack_head--;
- (*num_rooms_in_solution)++;
- }
- for (delta_index=0; delta_index < 4; delta_index++)
- {
- x_next=x+delta_x[delta_index][0];
- y_next=y+delta_y[delta_index][0];
- if (page[y_next][x_next] != ' ')
- {
- if (page[y_next][x_next] == 'W')
- {
- x_next+=delta_x[delta_index][0];
- y_next+=delta_y[delta_index][0];
- if (x_next < 0)
- (*adjacency)++;
- else
- if (x_next > max_x)
- (*adjacency)++;
- else
- if (y_next < 0)
- (*adjacency)++;
- else
- if (y_next > max_y)
- (*adjacency)++;
- else
- {
- if (page[y_next][x_next] == 'S')
- (*adjacency)++;
- }
- }
- }
- }
- return;
- }
-
- static void generate_maze(
- char **page,
- int max_x,
- int max_y,
- stack_rec *stack,
- int num_columns,
- int num_rows,
- int *seed)
- {
- static int delta_index_1;
- static int delta_index_2;
- static int digit;
- static int digit_num;
- static int passage_found;
- static int r_n [8];
- register int r_n_index_1;
- register int r_n_index_2;
- static int search_complete;
- static int stack_head;
- static int sum;
- static int tem_int;
- static int x;
- static int x_next;
- static int y;
- static int y_next;
-
- r_n[0]=seed[0]+1;
- r_n[1]=seed[1]+1;
- r_n[2]=seed[2]+1;
- r_n[3]=seed[3]+1;
- r_n[4]=seed[4]+1;
- r_n[5]=seed[5]+1;
- r_n[6]=seed[6]+1;
- r_n[7]=seed[7]+1;
- for (y=0; y <= max_y; ++y)
- for (x=0; x <= max_x; ++x)
- page[y][x]='W';
- sum=0;
- for (digit_num=1; digit_num <= 3; ++digit_num)
- {
- digit=r_n[0];
- r_n_index_1=0;
- for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
- {
- tem_int=r_n[r_n_index_2];
- r_n[r_n_index_1]=tem_int;
- digit+=tem_int;
- if (digit >= 29)
- digit-=29;
- r_n_index_1=r_n_index_2;
- }
- r_n[7]=digit;
- sum=29*sum+digit;
- }
- x=2*(sum % num_columns)+1;
- sum=0;
- for (digit_num=1; digit_num <= 3; ++digit_num)
- {
- digit=r_n[0];
- r_n_index_1=0;
- for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
- {
- tem_int=r_n[r_n_index_2];
- r_n[r_n_index_1]=tem_int;
- digit+=tem_int;
- if (digit >= 29)
- digit-=29;
- r_n_index_1=r_n_index_2;
- }
- r_n[7]=digit;
- sum=29*sum+digit;
- }
- y=2*(sum % num_rows)+1;
- page[y][x]=' ';
- stack_head=-1;
- do
- {
- delta_index_1=0;
- do
- {
- delta_index_2=r_n[0];
- r_n_index_1=0;
- r_n_index_2=1;
- while (r_n_index_2 < 8)
- {
- tem_int=r_n[r_n_index_2];
- r_n[r_n_index_1]=tem_int;
- delta_index_2+=tem_int;
- if (delta_index_2 >= 29)
- delta_index_2-=29;
- r_n_index_1=r_n_index_2;
- r_n_index_2++;
- }
- r_n[7]=delta_index_2;
- }
- while (delta_index_2 >= 24);
- passage_found=FALSE;
- search_complete=FALSE;
- while (! search_complete)
- {
- while ((delta_index_1 < 4) && (! passage_found))
- {
- x_next=x+2*delta_x[delta_index_1][delta_index_2];
- if (x_next <= 0)
- delta_index_1++;
- else
- if (x_next > max_x)
- delta_index_1++;
- else
- {
- y_next=y+2*delta_y[delta_index_1][delta_index_2];
- if (y_next <= 0)
- delta_index_1++;
- else
- if (y_next > max_y)
- delta_index_1++;
- else
- if (page[y_next][x_next] == 'W')
- passage_found=TRUE;
- else
- delta_index_1++;
- }
- }
- if (! passage_found)
- {
- if (stack_head >= 0)
- {
- delta_index_1=(int) (stack[stack_head].index_1);
- delta_index_2=stack[stack_head].index_2;
- x-=2*delta_x[delta_index_1][delta_index_2];
- y-=2*delta_y[delta_index_1][delta_index_2];
- stack_head--;
- delta_index_1++;
- }
- }
- search_complete=((passage_found)
- || ((stack_head == -1) && (delta_index_1 >= 4)));
- }
- if (passage_found)
- {
- stack_head++;
- stack[stack_head].index_1=(char) delta_index_1;
- stack[stack_head].index_2=delta_index_2;
- page[y_next][x_next]=' ';
- page[(y+y_next)/2][(x+x_next)/2]=' ';
- x=x_next;
- y=y_next;
- }
- }
- while (stack_head != -1);
- page[0][1]='S';
- page[max_y][max_x-1]=' ';
- return;
- }
-
- static void select_maze(
- char *seed_ptr,
- char **page,
- int max_x,
- int max_y,
- stack_rec *stack,
- int num_rooms_in_maze,
- int num_columns,
- int num_rows,
- long num_trials)
- {
- static int adjacency;
- static int counter_0;
- static int counter_1;
- static int counter_2;
- static int counter_3;
- static int counter_4;
- static int counter_5;
- static int counter_6;
- static int counter_7;
- static int min_adjacency;
- static int num_rooms_in_solution;
- static int num_rooms_in_solution_at_min;
- static int r_n [8];
- register int r_n_index_1;
- register int r_n_index_2;
- static int seed [8];
- static int seed_at_min [8];
- static long trial_num;
-
- while ((*seed_ptr == ' ')
- || (*seed_ptr == (char) 9))
- seed_ptr++;
- r_n_index_1=0;
- while ((r_n_index_1 < 8) && (*seed_ptr) && (*seed_ptr != '\n'))
- r_n[r_n_index_1++]=(int) (*(seed_ptr++) % 10);
- r_n_index_2=7;
- while (r_n_index_1 > 0)
- {
- r_n_index_1--;
- r_n[r_n_index_2]=r_n[r_n_index_1];
- r_n_index_2--;
- }
- while (r_n_index_2 >= 0)
- {
- r_n[r_n_index_2]=8;
- r_n_index_2--;
- }
- counter_0=r_n[0];
- counter_1=r_n[1];
- counter_2=r_n[2];
- counter_3=r_n[3];
- counter_4=r_n[4];
- counter_5=r_n[5];
- counter_6=r_n[6];
- counter_7=r_n[7];
- hash(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,&counter_5,
- &counter_6,&counter_7);
- get_cursor(&cursor_row,&cursor_column,&cursor_start,&cursor_stop);
- set_cursor_size((unsigned char) 32,(unsigned char) 32);
- titillator_index=0;
- min_adjacency=2*num_rooms_in_maze+1;
- num_rooms_in_solution_at_min=0;
- seed_at_min[0]=counter_0;
- seed_at_min[1]=counter_1;
- seed_at_min[2]=counter_2;
- seed_at_min[3]=counter_3;
- seed_at_min[4]=counter_4;
- seed_at_min[5]=counter_5;
- seed_at_min[6]=counter_6;
- seed_at_min[7]=counter_7;
- for (trial_num=num_trials; trial_num > 0L; --trial_num)
- {
- titillate();
- seed[0]=counter_0;
- seed[1]=counter_1;
- seed[2]=counter_2;
- seed[3]=counter_3;
- seed[4]=counter_4;
- seed[5]=counter_5;
- seed[6]=counter_6;
- seed[7]=counter_7;
- generate_maze(page,max_x,max_y,stack,num_columns,num_rows,&seed[0]);
- solve_maze(stack,page,&num_rooms_in_solution,&adjacency,max_x,max_y);
- if (3*num_rooms_in_solution >= num_rooms_in_maze)
- {
- if (adjacency < min_adjacency)
- {
- min_adjacency=adjacency;
- num_rooms_in_solution_at_min=num_rooms_in_solution;
- seed_at_min[0]=seed[0];
- seed_at_min[1]=seed[1];
- seed_at_min[2]=seed[2];
- seed_at_min[3]=seed[3];
- seed_at_min[4]=seed[4];
- seed_at_min[5]=seed[5];
- seed_at_min[6]=seed[6];
- seed_at_min[7]=seed[7];
- }
- else
- {
- if (adjacency == min_adjacency)
- {
- if (num_rooms_in_solution > num_rooms_in_solution_at_min)
- {
- num_rooms_in_solution_at_min=num_rooms_in_solution;
- seed_at_min[0]=seed[0];
- seed_at_min[1]=seed[1];
- seed_at_min[2]=seed[2];
- seed_at_min[3]=seed[3];
- seed_at_min[4]=seed[4];
- seed_at_min[5]=seed[5];
- seed_at_min[6]=seed[6];
- seed_at_min[7]=seed[7];
- }
- }
- }
- }
- increment(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,
- &counter_5,&counter_6,&counter_7);
- }
- generate_maze(page,max_x,max_y,stack,num_columns,num_rows,
- &seed_at_min[0]);
- solve_maze(stack,page,&num_rooms_in_solution,&adjacency,max_x,max_y);
- return;
- }
-
- static int substitution_high [100] =
- { 4,1,2,8,8,9,9,6,5,7,2,1,2,9,8,8,6,3,5,1,9,5,4,4,9,8,6,0,8,0,
- 6,0,2,4,1,9,2,0,7,4,7,3,0,0,2,6,8,9,4,0,8,3,2,3,2,5,2,4,6,9,
- 7,9,1,3,5,7,1,1,4,5,8,1,6,0,5,7,8,2,3,3,7,3,5,1,7,5,4,0,3,6,
- 3,7,7,1,9,4,0,5,6,6
- };
- static int substitution_low [100] =
- { 1,2,2,1,5,5,4,6,4,6,4,4,5,6,6,3,0,9,6,5,7,2,0,9,3,4,2,3,9,1,
- 9,9,9,3,8,9,3,4,1,5,0,5,2,7,0,8,8,0,4,5,0,3,6,8,1,7,8,8,7,1,
- 3,2,7,7,1,8,0,3,7,5,2,6,4,0,9,9,7,7,4,6,2,0,0,1,7,3,6,6,1,1,
- 2,4,5,9,8,2,8,8,3,5
- };
- static void hash(
- int *counter_0,
- int *counter_1,
- int *counter_2,
- int *counter_3,
- int *counter_4,
- int *counter_5,
- int *counter_6,
- int *counter_7)
- {
- register int iteration;
- static int seed_0;
- static int seed_1;
- static int seed_2;
- static int seed_3;
- static int seed_4;
- static int seed_5;
- static int seed_6;
- static int seed_7;
- register int substitution_index;
- static int tem_0;
- static int tem_1;
- static int tem_2;
-
- seed_0=(*counter_0);
- seed_1=(*counter_1);
- seed_2=(*counter_2);
- seed_3=(*counter_3);
- seed_4=(*counter_4);
- seed_5=(*counter_5);
- seed_6=(*counter_6);
- seed_7=(*counter_7);
- for (iteration=1; iteration <= 8; iteration++)
- {
- substitution_index=10*seed_1+seed_0;
- tem_0=substitution_low[substitution_index];
- tem_1=substitution_high[substitution_index];
- substitution_index=10*seed_3+seed_2;
- seed_0=substitution_low[substitution_index];
- tem_2=substitution_high[substitution_index];
- substitution_index=10*seed_5+seed_4;
- seed_2=substitution_low[substitution_index];
- seed_1=substitution_high[substitution_index];
- substitution_index=10*seed_7+seed_6;
- seed_5=substitution_low[substitution_index];
- seed_7=substitution_high[substitution_index];
- seed_3=tem_0;
- seed_6=tem_1;
- seed_4=tem_2;
- }
- (*counter_0)=seed_0;
- (*counter_1)=seed_1;
- (*counter_2)=seed_2;
- (*counter_3)=seed_3;
- (*counter_4)=seed_4;
- (*counter_5)=seed_5;
- (*counter_6)=seed_6;
- (*counter_7)=seed_7;
- return;
- }
-
- static void increment(
- int *counter_0,
- int *counter_1,
- int *counter_2,
- int *counter_3,
- int *counter_4,
- int *counter_5,
- int *counter_6,
- int *counter_7)
- {
- register tem;
-
- tem=(*counter_0)+1;
- if (tem <= 9)
- (*counter_0)=tem;
- else
- {
- (*counter_0)=0;
- tem=(*counter_1)+1;
- if (tem <= 9)
- (*counter_1)=tem;
- else
- {
- (*counter_1)=0;
- tem=(*counter_2)+1;
- if (tem <= 9)
- (*counter_2)=tem;
- else
- {
- (*counter_2)=0;
- tem=(*counter_3)+1;
- if (tem <= 9)
- (*counter_3)=tem;
- else
- {
- (*counter_3)=0;
- tem=(*counter_4)+1;
- if (tem <= 9)
- (*counter_4)=tem;
- else
- {
- (*counter_4)=0;
- tem=(*counter_5)+1;
- if (tem <= 9)
- (*counter_5)=tem;
- else
- {
- (*counter_5)=0;
- tem=(*counter_6)+1;
- if (tem <= 9)
- (*counter_6)=tem;
- else
- {
- (*counter_6)=0;
- tem=(*counter_7)+1;
- if (tem <= 9)
- (*counter_7)=tem;
- else
- (*counter_7)=0;
- }
- }
- }
- }
- }
- }
- }
- return;
- }
-
- static void draw_line(
- double x1,
- double y1,
- double x2,
- double y2,
- double x_max,
- double x_offset,
- double y_max,
- double cos_tilt,
- double sin_tilt,
- double pixels_per_x,
- double pixels_per_z,
- double rel_dist_of_user_from_screen)
- {
- static corner_rec end_point [2];
-
- get_corner(x1,y1,RELATIVE_HEIGHT_OF_WALL,pixels_per_x,pixels_per_z,
- cos_tilt,sin_tilt,rel_dist_of_user_from_screen,x_max,x_offset,y_max,
- &end_point[0]);
- get_corner(x2,y2,RELATIVE_HEIGHT_OF_WALL,pixels_per_x,pixels_per_z,
- cos_tilt,sin_tilt,rel_dist_of_user_from_screen,x_max,x_offset,y_max,
- &end_point[1]);
- moveto(end_point[0].x,end_point[0].y);
- lineto(end_point[1].x,end_point[1].y);
- return;
- }
-
- static void display_solution(
- int max_x,
- int max_y,
- char **page,
- double x_max,
- double x_offset,
- double y_max,
- double cos_tilt,
- double sin_tilt,
- double pixels_per_x,
- double pixels_per_z,
- double rel_dist_of_user_from_screen)
- {
- static int delta_index;
- static int path_found;
- static int x;
- static int x_next;
- static int x_previous;
- static double x_relative;
- static double x_relative_next;
- static int y;
- static int y_next;
- static double y_relative;
- static double y_relative_next;
- static int y_previous;
-
- setlinestyle(SOLID_LINE,0xffff,THICK_WIDTH);
- setcolor(SOLUTION_COLOR);
- x_previous=1;
- y_previous=-1;
- x=1;
- x_relative=(RELATIVE_WIDTH_OF_WALL+1.0)/2.0;
- y=0;
- y_relative=RELATIVE_WIDTH_OF_WALL/2.0;
- do
- {
- path_found=FALSE;
- for (delta_index=0; (! path_found); delta_index++)
- {
- x_next=x+delta_x[delta_index][0];
- y_next=y+delta_y[delta_index][0];
- if ((x_next != x_previous) || (y_next != y_previous))
- if (path_found=(page[y_next][x_next] == 'S'))
- {
- x_relative_next
- =x_relative+((double) delta_x[delta_index][0])/2.0;
- y_relative_next
- =y_relative+((double) delta_y[delta_index][0])/2.0;
- }
- }
- draw_line(x_relative,y_relative,x_relative_next,y_relative_next,
- x_max,x_offset,y_max,cos_tilt,sin_tilt,pixels_per_x,pixels_per_z,
- rel_dist_of_user_from_screen);
- x_relative=x_relative_next;
- y_relative=y_relative_next;
- x_previous=x;
- y_previous=y;
- x=x_next;
- y=y_next;
- }
- while ((x != max_x-1) || (y != max_y));
- return;
- }
-
- static void let_user_try_to_solve(
- int *key_pressed,
- int max_x,
- int max_y,
- char **computer_page,
- char **user_page,
- double x_max,
- double x_offset,
- double y_max,
- double cos_tilt,
- double sin_tilt,
- double pixels_per_x,
- double pixels_per_z,
- double rel_dist_of_user_from_screen)
- {
- static int delta_index_1;
- static int frequency;
- static int passage_found;
- static int x;
- static int x_next;
- static double x_relative;
- static double x_relative_next;
- static int y;
- static int y_next;
- static double y_relative;
- static double y_relative_next;
-
- setlinestyle(SOLID_LINE,0xffff,NORM_WIDTH);
- for (y=0; y <= max_y; y++)
- for (x=0; x <= max_x; x++)
- if (computer_page[y][x] == 'W')
- user_page[y][x]='W';
- else
- user_page[y][x]=' ';
- x=1;
- x_relative=(RELATIVE_WIDTH_OF_WALL+1.0)/2.0;
- y=1;
- y_relative=(RELATIVE_WIDTH_OF_WALL+1.0)/2.0;
- user_page[y][x]='S';
- setcolor(ADVANCE_COLOR);
- draw_line(x_relative,RELATIVE_WIDTH_OF_WALL/2.0,x_relative,y_relative,
- x_max,x_offset,y_max,cos_tilt,sin_tilt,pixels_per_x,pixels_per_z,
- rel_dist_of_user_from_screen);
- do
- {
- do
- {
- passage_found=TRUE;
- *key_pressed=getch();
- if ((*key_pressed != (int) 'Q')
- && (*key_pressed != (int) 'q')
- && (*key_pressed != (int) 'S')
- && (*key_pressed != (int) 's'))
- {
- if (*key_pressed == 0)
- {
- *key_pressed=getch();
- switch (*key_pressed)
- {
- case 72:
- delta_index_1=3;
- break;
- case 77:
- delta_index_1=2;
- break;
- case 80:
- delta_index_1=1;
- break;
- case 75:
- delta_index_1=0;
- break;
- default:
- {
- passage_found=FALSE;
- sound(120);
- delay(278);
- nosound();
- *key_pressed=(int) ' ';
- break;
- }
- }
- }
- else
- {
- switch (*key_pressed)
- {
- case 56:
- delta_index_1=3;
- break;
- case 54:
- delta_index_1=2;
- break;
- case 50:
- delta_index_1=1;
- break;
- case 52:
- delta_index_1=0;
- break;
- case 8:
- delta_index_1=0;
- break;
- default:
- passage_found=FALSE;
- break;
- }
- }
- if (passage_found)
- {
- x_next=x+delta_x[delta_index_1][0];
- if (x_next <= 0)
- passage_found=FALSE;
- else
- if (x_next >= max_x)
- passage_found=FALSE;
- else
- {
- y_next=y+delta_y[delta_index_1][0];
- if (y_next <= 0)
- passage_found=FALSE;
- else
- if (y_next > max_y)
- passage_found=FALSE;
- else
- if (user_page[y_next][x_next] == 'W')
- passage_found=FALSE;
- }
- }
- if (! passage_found)
- {
- passage_found=FALSE;
- sound(120);
- delay(278);
- nosound();
- }
- }
- }
- while ((! passage_found)
- && (*key_pressed != (int) 'Q')
- && (*key_pressed != (int) 'q')
- && (*key_pressed != (int) 'S')
- && (*key_pressed != (int) 's'));
- if ((*key_pressed != (int) 'Q')
- && (*key_pressed != (int) 'q')
- && (*key_pressed != (int) 'S')
- && (*key_pressed != (int) 's'))
- {
- x_next+=delta_x[delta_index_1][0];
- x_relative_next=x_relative+((double) (x_next-x))/2.0;
- y_next+=delta_y[delta_index_1][0];
- y_relative_next=y_relative+((double) (y_next-y))/2.0;
- if (y_next < max_y)
- {
- if (user_page[y_next][x_next] == 'S')
- {
- setcolor(BACKOUT_COLOR);
- user_page[y][x]=' ';
- }
- else
- {
- setcolor(ADVANCE_COLOR);
- user_page[y_next][x_next]='S';
- }
- draw_line(x_relative,y_relative,x_relative_next,
- y_relative_next,x_max,x_offset,y_max,cos_tilt,sin_tilt,
- pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
- }
- else
- {
- setcolor(ADVANCE_COLOR);
- draw_line(x_relative,y_relative,x_relative,y_relative+0.5,
- x_max,x_offset,y_max,cos_tilt,sin_tilt,
- pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
- }
- x=x_next;
- x_relative=x_relative_next;
- y=y_next;
- y_relative=y_relative_next;
- }
- }
- while ((y_next < max_y)
- && (*key_pressed != (int) 'Q')
- && (*key_pressed != (int) 'q')
- && (*key_pressed != (int) 'S')
- && (*key_pressed != (int) 's'));
- setcolor(0);
- outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
- "Arrows - Move S - Solve Q - Quit");
- if ((*key_pressed != (int) 'Q')
- && (*key_pressed != (int) 'q')
- && (*key_pressed != (int) 'S')
- && (*key_pressed != (int) 's'))
- {
- setcolor(NUM_COLORS-4);
- outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,"Congratulations!");
- frequency=10;
- for (delta_index_1=1; delta_index_1 <= 100;
- delta_index_1++)
- {
- sound(frequency);
- delay(56);
- nosound();
- frequency+=10;
- };
- setcolor(0);
- outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,"Congratulations!");
- setcolor(NUM_COLORS-4);
- outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
- "S - Solve Other - Restart program");
- while (kbhit())
- {
- *key_pressed=getch();
- if (*key_pressed == 0)
- {
- *key_pressed=getch();
- *key_pressed=(int) ' ';
- }
- }
- *key_pressed=getch();
- if (*key_pressed == 0)
- {
- *key_pressed=getch();
- *key_pressed=(int) ' ';
- }
- setcolor(0);
- outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
- "S - Solve Other - Restart program");
- }
- return;
- }
-